/**
 * This file is Copyright © 2008 Software Craftsmen Limited. All Rights Reserved.
 */
package com.softwarecraftsmen.orogeny.actions.keys;

import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static java.lang.String.format;
import java.security.Key;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;
import java.security.cert.Certificate;
import static java.util.Locale.UK;

public class ConvenientKey
{
	private final String keyAliasName;
	private final char[] keyPassword;

	public ConvenientKey(final @NotNull String keyAliasName, final @Nullable char[] keyPassword)
	{
		this.keyAliasName = keyAliasName.toUpperCase(UK);
		this.keyPassword = keyPassword;
	}

	@NotNull
	public Key getPublicKey(final @NotNull KeyStore keyStore)
	{
		try
		{
			return keyStore.getKey(keyAliasName, keyPassword);
		}
		catch (KeyStoreException e)
		{
			throw new IllegalStateException("Should never happen", e);
		}
		catch (NoSuchAlgorithmException e)
		{
			throw new IllegalStateException("Should never happen", e);
		}
		catch (UnrecoverableKeyException e)
		{
			throw new IllegalArgumentException("Key could not be recovered, probably because the password is wrong", e);
		}
	}

	@NotNull
	public Certificate[] getCertificateChain(final @NotNull KeyStore keyStore)
	{
		try
		{
			return keyStore.getCertificateChain(keyAliasName);
		}
		catch (KeyStoreException e)
		{
			throw new IllegalArgumentException("Should never happen", e);
		}
	}

	@NotNull
	public String signatureFileName()
	{
		return format(UK, "META-INF/%1$s.SF", keyAliasName);
	}

	@NotNull
	public String signatureBlockFileName(final @NotNull String privateKeyAlgorithm)
	{
		return format(UK, "META-INF/%1$s.%2$s", keyAliasName, privateKeyAlgorithm);
	}

	@NotNull
	public static SpecifyKeyAliasName key(final @NotNull String keyAliasName)
	{
		return new SpecifyKeyAliasName(keyAliasName);
	}

	public static final class SpecifyKeyAliasName
	{
		private final String keyAliasName;

		private SpecifyKeyAliasName(final @NotNull String keyAliasName) {this.keyAliasName = keyAliasName;}

		@NotNull
		public ConvenientKey password(final @Nullable String password)
		{
			if (password == null)
			{
				return new ConvenientKey(keyAliasName, null);
			}
			return new ConvenientKey(keyAliasName, password.toCharArray());
		}
	}
}
